using System;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;

using System.Xml;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (Pty) ltd
	Author:		Alan Benington	
	Started:	2005-05-15	
	Status:		release	
	Version:	2.0.0
	Buidl:		20070524
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/
	
/*	-----------------------------------------------------------------------	
	Development Notes:
	==================
	20070524:	Modification for .Net 2.0
	-----------------------------------------------------------------------	*/
	
namespace umlungu.engineX.webX {
	/// <summary>
	/// umlungu engineX web framework, xxx class.
	/// </summary>
	public class remoteX
	{
		/// <summary>
		/// Local objects and properties
		/// </summary>
		private bool debug, proxy;
		private System.Web.UI.Page page;
		private string proxy_name, proxy_pass;
		private int timeout;
		private long responseLength;
		private static int defaultTimeout = 10000;
		// private string type, name, requestUrl;	// not used for now
		//private DynamicWebServiceProxy soap;
		
		private Uri uri;
		public string Url	{
			get	{	return uri.ToString();	}	
			set	{	uri = new Uri(value);	}
		}
		
		#region Public methods
		/// <summary>Constructor</summary>
		public remoteX(System.Web.UI.Page thispage, bool wantdebug) {
			page = thispage;
			proxy = false;
			proxy_name = "";
			proxy_pass = "";
			debug = wantdebug;
			intialise();
		}
		public remoteX(System.Web.UI.Page thispage, bool wantproxy, string proxyname, string proxypass, bool wantdebug) {
			page = thispage;
			proxy = (wantproxy) ? true : false;
			if (proxy) {
				proxy_name = proxyname;
				proxy_pass = proxypass;
			}
			debug = wantdebug;
			intialise();
		}
		/// <summary>
		/// Get:: method to call a specified URL
		/// </summary>
		public string Get(string url) {
			uri = new Uri(url);
			return(Get());
		}
		public string Get() {
			_Debug("Get", "uri:", uri.ToString());
			HttpWebRequest urlReq = (HttpWebRequest)WebRequest.Create(uri);
			urlReq.Timeout = timeout;
			string Content = retrieveURL(urlReq);
			return((Content == null)? "" : Content);
		}
		public string Post() {
			_Debug("Post", "uri:", uri.ToString());
			return(Post(uri.Query.Substring(1)));	// get rid of the '?'
		}
		public string Post(string poststr) {
			_Debug("Post", "poststr:", poststr);
			
			string pathstr = uri.GetLeftPart(UriPartial.Path);
			uri = new Uri(pathstr);
			_Debug("Post", "uri:", uri.ToString());
			
			StreamWriter postWriter = null;
			HttpWebRequest urlReq = (HttpWebRequest)WebRequest.Create(uri);
			urlReq.Credentials = System.Net.CredentialCache.DefaultCredentials;
			urlReq.Timeout = timeout;
			urlReq.Method = "POST";
			urlReq.ContentLength = poststr.Length;
			urlReq.ContentType = "application/x-www-form-urlencoded";
			// write the fields to be posted...
			try {
				postWriter = new StreamWriter(urlReq.GetRequestStream());
				postWriter.Write(poststr);
			} catch (Exception except) {
				exceptionX exceptX = new exceptionX("remoteX_call", "system_error", except);
				_Debug("Post", exceptX.Xml.DocumentElement.OuterXml);
			} finally {
				postWriter.Close();
			}
			string Content = retrieveURL(urlReq);
			return((Content == null)? "" : Content);
		}
		/// <summary>
		/// Method: Soap
		///		- Calls the dynamic proxy to Invoke the SOAP call
		///		- Note that this expects the result to be an XmlNode.
		/// </summary>
		/* 
		public string Soap() {
			_Debug("Soap", "soap:", (soap == null)? "null" : soap.ToString());
			object obj = soap.InvokeCall();
			_Debug("Soap", "obj:", obj.ToString());
			XmlNode result = (XmlNode) soap.InvokeCall();
			_Debug("Soap..");
			return(result.OuterXml);
		}
		*/
		/// <summary>
		/// Method: GetUrl
		/// 	- Creates the url to call a umlungu-type web service via urlstr (ie using a http get)
		/// 	- formatted as: 'http://www.whatever.com/webservice.asp?service=XXX&process=YYY&param1=111...'
		/// </summary>
		public Uri GetUrl(string baseurl, string srvstr, string prcstr, string paramstr, bool wantflds, string checkname, string checkfld, bool checkincr) {
			Uri baseUri = new Uri(baseurl);
			string thisurl = String.Concat("?service=", srvstr, "&process=", prcstr, "&", paramstr);
			if (wantflds)
				thisurl = String.Concat(thisurl, getFormFields(checkname, checkfld, checkincr));
			return(new Uri(baseUri, thisurl));
		}
		/// <summary>
		/// Method: GetUrlX
		/// 	- Creates the url to call a umlungu-type .net web service via urlstr (ie using a http get)
		/// 	- formatted as: 'http://www.whatever.com/webservice.aspx?service=XXX&operation=YYY&param1=111...'
		/// </summary>
		public Uri GetUrlX(string baseurl, string srvstr, string opstr, string paramstr, bool wantflds, string checkname, string checkfld, bool checkincr) {
			Uri baseUri = new Uri(baseurl);
			string thisurl = String.Concat("?service=", srvstr, "&operation=", opstr, "&", paramstr);
			if (wantflds)
				thisurl = String.Concat(thisurl, getFormFields(checkname, checkfld, checkincr));
			return(new Uri(baseUri, thisurl));
		}
		/// <summary>
		/// Method: GetUrlNet
		/// 	- Creates the url to call a .Net-type web service via urlstr (ie using a http get)
		/// 	- formatted as: 'http://www.whatever.com/webservice.asmx/process?param1=111...'
		/// </summary>
		public Uri GetUrlNet(string baseurl, string srvstr, string opstr, string paramstr, bool wantflds, string checkname, string checkfld, bool checkincr) {
			Uri baseUri = new Uri(baseurl);
			string thisurl = String.Concat(opstr, "?", paramstr);
			if (wantflds) {
				string fldsurl = getFormFields(checkname, checkfld, checkincr);
				if (paramstr == "" && fldsurl != "")
					fldsurl = fldsurl.Substring(1);	// remove the first '&'
				thisurl = String.Concat(thisurl, fldsurl);
			}
			return(new Uri(baseUri, thisurl));
		}
		/// <summary>
		/// Method: SetUrl
		/// </summary>
		public void SetUrl(string url) {
			uri = new Uri(url);
		}
		public void SetUrl(string type, string baseurl, string srvstr, string prcstr, string paramstr, bool wantflds, string checkname, string checkfld, bool checkincr) {
			string thisurl;
			switch (type) {
				case ".net": 		thisurl = String.Concat(baseurl, "/", prcstr, "?", paramstr);	break;
				case "umlungux":	thisurl = String.Concat(baseurl, "?service=", srvstr, "&operation=", prcstr, "&", paramstr);	break;
				default:
				case "umlungu":		thisurl = String.Concat(baseurl, "?service=", srvstr, "&process=", prcstr, "&", paramstr);	break;
			}
			if (wantflds) {
				string fldsurl = getFormFields(checkname, checkfld, checkincr);
				if (paramstr == "" && fldsurl != "")
					fldsurl = fldsurl.Substring(1);	// remove the first '&'
				thisurl = String.Concat(thisurl, fldsurl);
			}
			uri = new Uri(thisurl);
		}
		/// <summary>
		/// Method: SetSoap
		/// </summary>
		/*
		public void SetSoap(string thisbase, string typeName, string methodName, object[] parameters) {
			_Debug("SetSoap", "thisbase:", thisbase, " typeName:", typeName, " methodName:", methodName);
			soap = new DynamicWebServiceProxy();
			soap.WSDL = String.Concat(thisbase, "?WSDL");
			soap.TypeName = typeName;
			soap.MethodName = methodName;
			// Add the parameters from the object array
			foreach (object param in parameters) {
				soap.AddParameter(param);
			}
		}
		*/
		#endregion

		#region Protected methods
		/// <summary>
		/// Method description
		/// </summary>
		protected void _Debug(string label, params string[] outparam) {
			if (debug) {
				page.Response.Write("\n<!-- remoteX.");
				page.Response.Write(label);
				page.Response.Write("::\n");
				for (int i=0; i < outparam.Length; i++)
					page.Response.Write(outparam[i]);
				page.Response.Write("\n-->\n");
			}
		}
		#endregion

		#region Private methods
		/// <summary>
		/// Method description
		/// </summary>
		private void intialise() {
			timeout = defaultTimeout;
		}
		private void intialise(int time) {
			timeout = time;
		}
		/// <summary>
		///	retrieveURL:: method to retrieves the contents of a specified URL in response to a request
		///	</summary>
		private string retrieveURL(HttpWebRequest request) {
			HttpWebResponse response = (HttpWebResponse)request.GetResponse();
			Stream responseStream = response.GetResponseStream();
			responseLength = response.ContentLength;
			StreamReader reader = new StreamReader (responseStream);
			return reader.ReadToEnd();
		}
		/// <summary>
		/// getFormFields:: Append the form fields to the url string to pass as parameters to the web service
		/// </summary>
		private string getFormFields(string chkname, string chkfld, bool chkincr) {
			Regex re = new Regex("%0D%0A");
			string thisval , thisurl = "", thisfld;
			int ndx, incr = 0;
			for (int i=0; i < page.Request.Form.Count; i++) { 
				thisval = page.Request.Form.Get(i);
				thisfld = page.Request.Form.GetKey(i);
				if (chkname != "") {
					ndx = thisfld.IndexOf(chkname);
					if (ndx >= 0) {
						thisval = thisfld.Substring(chkname.Length);
						thisfld = chkfld;
						if (chkincr) {
							incr++;
							thisfld = String.Concat(thisfld, incr.ToString());
						}
					}
				}
				//thisval = escape(thisval);	// remove crlf's ! (escape makes them %0D%0A)
				thisval = re.Replace(thisval, "%20%20");
				thisurl = String.Concat(thisurl, "&", thisfld, "=", thisval); 
				}
			return(thisurl);
		}
		#endregion
	}
}
		
